/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.flavienlaurent.discrollview.lib;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.NestedScrollView;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;



/**
 * DiNetscrollView
 *
 * @since 2021-03-01
 */
public class DiNetscrollView extends NestedScrollView {
    private static final int TWO = 2;
    private static String tag = DiscrollView.class.getSimpleName();
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, tag);
    private DiscrollViewContent mContent;

    /**
     * 构造函数
     *
     * @param context
     */
    public DiNetscrollView(Context context) {
        super(context);
    }

    /**
     * 构造函数
     *
     * @param context
     * @param attrSet
     */
    public DiNetscrollView(Context context, AttrSet attrSet) {
        super(context, attrSet);
    }

    /**
     * 构造函数
     *
     * @param context
     * @param attrSet
     * @param styleName
     */
    public DiNetscrollView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
    }

    /**
     * onFinishInflate
     *
     * @throws IllegalStateException
     */
    public void onFinishInflate() {
        if (getChildCount() != 1) {
            throw new IllegalStateException("Discrollview must host one child.");
        }
        Component content = getComponentAt(0);
        if (!(content instanceof DiscrollViewContent)) {
            throw new IllegalStateException("Discrollview must host a DiscrollViewContent.");
        }
        mContent = (DiscrollViewContent) content;
        if (mContent.getChildCount() < TWO) {
            throw new IllegalStateException("Discrollview must have at least 2 children.");
        }
        this.setScrolledListener(new Component.ScrolledListener() {
            @Override
            public void onContentScrolled(Component component, int i, int i1, int i2, int i3) {
                setupFirstView();
                onScrollChanged(i1);
            }
        });
    }

    private void setupFirstView() {
        Component first = mContent.getComponentAt(0); // first first take all the parent height
        if (first != null) {
            first.getLayoutConfig().height = getHeight();
        }
    }

    /**
     * clamp
     *
     * @param value
     * @param max
     * @param min
     * @return float
     */
    public static float clamp(float value, float max, float min) {
        return Math.max(Math.min(value, min), max);
    }

    /**
     * getAbsoluteBottom
     *
     * @return int
     */
    private int getAbsoluteBottom() {
        Component last = getComponentAt(getChildCount() - 1);
        if (last == null) {
            return 0;
        }
        return last.getBottom();
    }

    /**
     * onScrollChanged
     *
     * @param top
     */
    private void onScrollChanged(int top) {
        int scrollViewHeight = getHeight();
        int scrollViewBottom = getAbsoluteBottom();
        int scrollViewHalfHeight = scrollViewHeight / TWO;
        for (int index = 0; index < mContent.getChildCount();index++) {
            Component child = mContent.getComponentAt(index);
            if (!(child instanceof Discrollvable)) {
                continue;
            }
            Discrollvable discrollvable = (Discrollvable) child;
            int discrollvableTop = child.getTop();
            int discrollvableHeight = child.getHeight();
            int discrollvableAbsoluteTop = discrollvableTop - top;
            if (scrollViewBottom - child.getBottom()
                < discrollvableHeight + scrollViewHalfHeight) { // 卸料器太大，到达中心时无法卸料器,可拆卸中心。把它从上面卸下来。
                if (discrollvableAbsoluteTop <= scrollViewHeight) { // 可拆卸的顶部到达DiscrollView底部
                    int visibleGap = scrollViewHeight - discrollvableAbsoluteTop;
                    discrollvable.onDiscrollve(clamp(visibleGap / (float) discrollvableHeight, 0.0f, 1.0f));
                } else {
                    discrollvable.onResetDiscrollve();
                }
            } else {
                if (discrollvableAbsoluteTop
                    <= scrollViewHalfHeight) { // the Discrollvable center reaches the DiscrollView center
                    int visibleGap = scrollViewHalfHeight - discrollvableAbsoluteTop;
                    discrollvable.onDiscrollve(clamp(visibleGap / (float) discrollvableHeight, 0.0f, 1.0f));
                } else {
                    discrollvable.onResetDiscrollve();
                }
            }
        }
    }
}

